﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Reflection;

namespace HDJ.Framework.Core
{
    [System.Serializable]
    public class TableBase
    {
        public virtual bool CompareKey(string key) { return false; }

    }
    /// <summary>
    /// 表格的所有数据
    /// </summary>
    public class TableData
    {
        /// <summary>
        /// 配置描述
        /// </summary>
        public string description = "";
        /// <summary>
        /// 字段描述信息(Dictionary<字段名,字段具体信息>)
        /// </summary>
        public Dictionary<string, TableFieldInfo> fieldInfos = new Dictionary<string, TableFieldInfo>();
        /// <summary>
        /// 表格里转换成类的数据（Dictionary<key,一行数据（Dictionary<字段名,数据>）>）
        /// </summary>
        public Dictionary<string, Dictionary<string,object>> datas = new Dictionary<string, Dictionary<string, object>>();

        /// <summary>
        /// 添加字段
        /// </summary>
        /// <param name="f"></param>
        /// <param name="index"></param>
        public void AddField(TableFieldInfo f,int index)
        {
            if(fieldInfos.ContainsKey(f.name))
            {
                Debug.LogError("已有字段：" + f.name);
                return;
            }
            List<TableFieldInfo> list = new List<TableFieldInfo>(fieldInfos.Values);

            if (index < 0)
                index = 0;
            if (index >= list.Count)
                list.Add(f);
            else
                list.Insert(index, f);
            fieldInfos.Clear();

            foreach (var item in list)
            {
                fieldInfos.Add(item.name, item);
            }

            foreach (var item in datas.Values)
            {
                item.Add(f.name, f.defultValue);
            }
        }

        /// <summary>
        /// 删除字段
        /// </summary>
        /// <param name="fieldName"></param>
        public void DeleteField(string fieldName)
        {
            fieldInfos.Remove(fieldName);
            foreach (var item in datas.Values)
            {
                item.Remove(fieldName);
            }
        }
        /// <summary>
        /// 改变字段名字
        /// </summary>
        /// <param name="oldFieldName"></param>
        /// <param name="newFieldName"></param>
        public void RenameField(string oldFieldName, string newFieldName)
        {
            if (oldFieldName == newFieldName)
                return;
            if (fieldInfos.ContainsKey(newFieldName))
                return;
            if (fieldInfos.ContainsKey(oldFieldName))
            {
                List<TableFieldInfo> list = new List<TableFieldInfo>(fieldInfos.Values);
                fieldInfos.Clear();

                foreach (var item in list)
                {
                    if (item.name == oldFieldName)
                    {
                        item.name = newFieldName;
                    }
                    fieldInfos.Add(item.name, item);
                }

                foreach (var item in datas.Values)
                {
                    object value = item[oldFieldName];
                    item.Remove(oldFieldName);
                    item.Add(newFieldName, value);

                }
            }
            else
            {
                Debug.LogError("RenameField，没有字段：" + oldFieldName);
            }

        }
        /// <summary>
        /// 改变字段类型
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="fieldValueType"></param>
        /// <param name="defultValue"></param>
        public void ChangeFieldType(string fieldName, Type fieldType, object defultValue=null)
        {
            TableFieldInfo info = fieldInfos[fieldName];
            info.fieldType = fieldType;
            //info.enumType = enumType;
            Type type = fieldType; //TableUtils.TableFieldType2Type(fieldType,enumType);
            if(info.defultValue.GetType() != type)
            {
                info.defultValue = TableTypeSupportController.Instance.GetDefultData(type);// TableUtils.TableStringData2Value(type, null);
            }
            if(defultValue!=null && defultValue.GetType()==type && !TableUtils.ValueEquals(defultValue, info.defultValue))
            {
                info.defultValue = defultValue;
            }
            foreach (var item in datas.Values)
            {
                object value = item[fieldName];

                if (type != value.GetType())
                {
                    item[fieldName] = defultValue;
                }
            }
        }

        /// <summary>
        /// 添加一行数据
        /// </summary>
        /// <param name="index"></param>
        /// <param name="data"></param>
        public void AddLineData(int index, string key, Dictionary<string, object> useValues =null)
        {
            Dictionary<string, object> lineData = useValues;
            if (lineData == null)
            {
                 lineData = new Dictionary<string, object>();
                List<TableFieldInfo> infos = new List<TableFieldInfo>(fieldInfos.Values);
                for (int i = 0; i < infos.Count; i++)
                {
                    TableFieldInfo info = infos[i];
                    if (i == 0)
                    {
                        lineData.Add(info.name, key);
                    }
                    else
                    {
                        lineData.Add(info.name, info.defultValue);
                    }
                }
            }

            List<string> keys = new List<string>(datas.Keys);
            List<Dictionary<string, object>> values = new List<Dictionary<string, object>>(datas.Values);
            datas.Clear();
            if (index < 0)
                index = 0;
            if (index >= keys.Count)
            {
                keys.Add(key);
                values.Add(lineData);
            }
            else
            {
                keys.Insert(index, key);
                values.Insert(index, lineData);
            }

            for (int i = 0; i < keys.Count; i++)
            {
                datas.Add(keys[i], values[i]);
            }
        }     
        /// <summary>
        /// 移除一行数据
        /// </summary>
        /// <param name="index"></param>
        public void RemoveLineData(int index)
        {
            List<string> keys = new List<string>(datas.Keys);
            if (index < 0 || index >= keys.Count)
                return;

            string key = keys[index];
            datas.Remove(key);
        }
        /// <summary>
        /// 移动一行数据
        /// </summary>
        /// <param name="index"></param>
        /// <param name="toIndex"></param>
        public void MoveLineData(int index,int toIndex)
        {
            if (index < 0 || index > datas.Count - 1)
                return;
            if (toIndex<0)
            {
                toIndex = 0;
            }
            else if (toIndex >= datas.Count)
            {
                toIndex = datas.Count - 1;
            }
            if (index == toIndex)
                return;
            List<string> keys = new List<string>(datas.Keys);
            List<Dictionary<string, object>> values = new List<Dictionary<string, object>>(datas.Values);
            string k = keys[index];
            Dictionary<string, object> v = values[index];

            keys.RemoveAt(index);
            values.RemoveAt(index);
            if (toIndex >= keys.Count)
            {
                keys.Add(k);
                values.Add(v);
            }
            else
            {
                keys.Insert(toIndex, k);
                values.Insert(toIndex, v);
            }
            datas.Clear();
            for (int i = 0; i < keys.Count; i++)
            {
                datas.Add(keys[i], values[i]);
            }
        }
        /// <summary>
        /// 移动字段位置
        /// </summary>
        /// <param name="index"></param>
        /// <param name="toIndex"></param>
        public void MoveField(int index, int toIndex)
        {
            if (index < 0 || index > fieldInfos.Count - 1)
                return;
            if (toIndex < 0)
            {
                toIndex = 0;
            }
            else if (toIndex >= fieldInfos.Count)
            {
                toIndex = fieldInfos.Count - 1;
            }
            if (index == toIndex)
                return;

            List<TableFieldInfo> values = new List<TableFieldInfo> (fieldInfos.Values);
            TableFieldInfo v = values[index];


            values.RemoveAt(index);
            if (toIndex >= values.Count)
            {
                values.Add(v);
            }
            else
            {
                values.Insert(toIndex, v);
            }
            fieldInfos.Clear();
            for (int i = 0; i < values.Count; i++)
            {
                fieldInfos.Add(values[i].name, values[i]);
            }
        }

    }
    /// <summary>
    /// 字段描述信息
    /// </summary>
    public class TableFieldInfo
    {
        [ShowGUIName("字段名")]
        public string name = "";
        [ShowGUIName("描述")]
        public string description = "";
        [ShowGUIName("数据类型")]
        public Type fieldType;
        /// <summary>
        /// 枚举的全类型名
        /// </summary>
        //public string enumType = "";
        [ShowGUIName("默认值")]
        public object defultValue=null;
        /// <summary>
        /// 用于Editor编辑的作用标签
        /// </summary>
        public string tag="";

        public TableFieldInfo() { }
        public TableFieldInfo(string name, Type fieldType)
        {
            this.name = name;
            this.fieldType = fieldType;
          //  Type type = TableUtils.TableFieldType2Type(fieldType, enumType);
            this.defultValue = TableTypeSupportController.Instance.GetDefultData(fieldType);
        }
        public TableFieldInfo Clone()
        {
            TableFieldInfo info = new TableFieldInfo();
            info.name = name;
            info.description = description;
            info.fieldType = fieldType;
            //info.enumType = enumType;
            info.defultValue = defultValue;
            info.tag = tag;
            return info;
        }
    }

    //public enum TableFieldType
    //{
    //    Int,
    //    Float,
    //    Bool,
    //    String,
    //    Vector2,
    //    Vector3,
    //    Enum,
    //    Int_Array,
    //    Float_Array,
    //    Bool_Array,
    //    String_Array,
    //    Vector2_Array,
    //    Vector3_Array,
    //}
}
